﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Runtime.Serialization.Json;
using System.Threading;
using System.ServiceModel;

namespace Testy
{
    public partial class MainPage : UserControl
    {
        SynchronizationContext syncontext;

        List<User> Users;
        string Token = "";
        Project ProjectRoot;
        List<Project> ProjectList = new List<Project>();
        List<ProjectIssue> Issues;

        Project Selected_Project = null;
        ProjectIssue Selected_ProjectIssue = null;
        ProjectIssueDetail Selected_ProjectIssueDetail = null;

        public MainPage()
        {
            InitializeComponent();

            syncontext = SynchronizationContext.Current;

            //web service debug
            this.Loaded += delegate
            {
                //set UI logic
                ProjectsTreeView.Items.Clear();
                IssuesListBox.Items.Clear();
                IssuesDetailsListBox.Items.Clear();
                
                //need to recode
                ProjectsTreeView.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(ProjectsTreeView_SelectedItemChanged);
                IssuesListBox.SelectionChanged += new SelectionChangedEventHandler(IssuesListBox_SelectionChanged);
                IssuesDetailsListBox.SelectionChanged += new SelectionChangedEventHandler(IssuesDetailsListBox_SelectionChanged);

                Button_DoLogin.Click += new RoutedEventHandler(Button_DoLogin_Click);
                Button_DoLogout.Click += new RoutedEventHandler(Button_DoLogout_Click);

                button_addComment.Click += new RoutedEventHandler(button_addComment_Click);

                button_applyChangeIssueTitle.Click += new RoutedEventHandler(button_applyChangeIssueTitle_Click);

                Button_Add_Bug.Click += new RoutedEventHandler(Button_Add_BugTodoIdea_Click);
                Button_Add_Idea.Click += new RoutedEventHandler(Button_Add_BugTodoIdea_Click);
                Button_Add_ToDo.Click += new RoutedEventHandler(Button_Add_BugTodoIdea_Click);

                button_prj_add.Click += new RoutedEventHandler(button_prj_add_Click);
                button_prj_rename.Click += new RoutedEventHandler(button_prj_rename_Click);
                button_prj_delete.Click += new RoutedEventHandler(button_prj_delete_Click);

                Button_addnewuser.Click += new RoutedEventHandler(Button_addnewuser_Click);

                BLClient.Service_GetUsers(syncontext, 
                    (object objUsr) => 
                    {
                        if (objUsr != null)
                        {
                            Users = (List<User>)objUsr;                            
                            UsersListBox.ItemsSource = Users;
                        }
                    });

                BLClient.Service_GetProjects(syncontext, SetProjectListAndPerformProjects);

                //debug
                TextBox_Login.Text = "Joe";
                TextBox_Password.Text = "black";                
            };            
        }

        void Button_addnewuser_Click(object sender, RoutedEventArgs e)
        {
            if ((TextBox_newusername.Text != "") && (TextBox_newuserpassword.Text != ""))
            {
                BLClient.Service_AddUser(TextBox_newusername.Text, TextBox_newuserpassword.Text, syncontext,
                    (object obj) =>
                    {
                        bool res = (bool)obj;
                        if (res)
                        {
                            BLClient.Service_GetUsers(syncontext,
                                (object objUsr) =>
                                {
                                    if (objUsr != null)
                                    {
                                        Users = (List<User>)objUsr;                                        
                                        UsersListBox.ItemsSource = Users;
                                    }
                                });
                        }
                        else MessageBox.Show("Can't create new user");
                    });
            }
        }

        void button_prj_delete_Click(object sender, RoutedEventArgs e)
        {
            if ((Selected_Project != null) && (Token != ""))
            {
                BLClient.Service_AddDeleteRenameProject(Token, Selected_Project.ID, false, null,
                    syncontext,
                    (object obj) =>
                    {
                        bool res = (bool)obj;
                        if (res)
                        {
                            BLClient.Service_GetProjects(syncontext, SetProjectListAndPerformProjects);
                            ClearIssueAndIssueDetailVariableaAndUI();                            
                        }
                        else MessageBox.Show("Can't delete project");
                    });
            }
        }

        void button_prj_rename_Click(object sender, RoutedEventArgs e)
        {
            if ((Selected_Project != null) && (textbox_renamedprojectname.Text != "") && (Token != ""))
            {
                BLClient.Service_AddDeleteRenameProject(Token, Selected_Project.ID, false, textbox_renamedprojectname.Text,
                    syncontext,
                    (object obj) =>
                    {
                        bool res = (bool)obj;
                        if (res)
                        {
                            BLClient.Service_GetProjects(syncontext, SetProjectListAndPerformProjects);
                            ClearIssueAndIssueDetailVariableaAndUI();
                            textbox_renamedprojectname.Text = "";
                        }
                        else MessageBox.Show("Can't rename project");
                    });
            }
        }

        void button_prj_add_Click(object sender, RoutedEventArgs e)
        {
            if ((Selected_Project != null) && (textbox_newprojectname.Text != "") && (Token != ""))
            {
                BLClient.Service_AddDeleteRenameProject(Token, Selected_Project.ID, true, textbox_newprojectname.Text,
                    syncontext, 
                    (object obj) => 
                    {
                        bool res = (bool)obj;
                        if (res)
                        {
                            BLClient.Service_GetProjects(syncontext, SetProjectListAndPerformProjects);
                            ClearIssueAndIssueDetailVariableaAndUI();
                            textbox_newprojectname.Text = "";
                        }
                        else MessageBox.Show("Can't add new subproject");
                    });
            }
        }

        void Button_Add_BugTodoIdea_Click(object sender, RoutedEventArgs e)
        {            
            if ((Token != "") && (Selected_Project != null))
            {
                int n = int.Parse((sender as Button).Tag.ToString());
                ProjectIssueType pit;
                if (n == 0) pit = ProjectIssueType.ToDo;
                else if (n == 1) pit = ProjectIssueType.Idea;
                else pit = ProjectIssueType.Bug;

                BLClient.Service_PostIssue(Token, Selected_Project.ID, "new issue", pit, null, syncontext, 
                    (object obj) => 
                    {
                        bool res = (bool)obj;
                        if (res)
                        {                            
                            BLClient.Service_GetProjects(syncontext, SetProjectListAndPerformProjects);
                            BLClient.Service_GetIssues(Token, syncontext,
                                (object obj2) =>
                                {
                                    if (obj2 != null)
                                    {
                                        Issues = (List<ProjectIssue>)obj2;

                                        Project prjToView = null;
                                        string previousSelectedProjectID = Selected_Project.ID;
                                        foreach (Project prIn in ProjectList)
                                        {
                                            if (prIn.ID == previousSelectedProjectID)
                                            {
                                                prjToView = prIn;
                                                break;
                                            }
                                        }
                                        if (prjToView != null)
                                        {
                                            Selected_Project = prjToView;
                                            PerformIssuesOfSelectedProject();
                                        }
                                        else
                                        {
                                            ClearIssueAndIssueDetailVariableaAndUI();
                                        }
                                    }
                                });                            
                        }
                        else MessageBox.Show("Can't add new issue");
                    });
            }
        }

        void button_applyChangeIssueTitle_Click(object sender, RoutedEventArgs e)
        {
            if ((textbox_projectIssueTitle.Text != null) && (Selected_ProjectIssue != null))
            {
                string id = Selected_ProjectIssue.ID;
                BLClient.Service_UpdateIssueName(Token, Selected_ProjectIssue.ID, textbox_projectIssueTitle.Text,
                    syncontext, (object obj) =>
                    {
                        bool res = (bool)obj;
                        if (res)
                        {
                            Selected_ProjectIssue.Name = textbox_projectIssueTitle.Text; //temp
                            if (IssuesListBox.SelectedIndex > -1)
                            {
                                int oldindex = IssuesListBox.SelectedIndex;
                                IssuesListBox.Items.Remove(Selected_ProjectIssue);
                                IssuesListBox.Items.Insert(oldindex, Selected_ProjectIssue);
                                IssuesListBox.SelectedIndex = oldindex;
                            }
                        }
                        else MessageBox.Show("Can't update issue title");
                    });
            }
        }

        void button_addComment_Click(object sender, RoutedEventArgs e)
        {
            if ((Selected_ProjectIssue != null) && (Token != null) && (textbox_newComment.Text != ""))
            {
                BLClient.Service_PostIssueDetail(Token, Selected_ProjectIssue.ID, textbox_newComment.Text, syncontext,
                    (object obj) => 
                    {
                        bool res = (bool)obj;
                        if (res)
                        {
                            //BLClient.Service_GetProjects(syncontext, SetProjectListAndPerformProjects);
                            BLClient.Service_GetIssues(Token, syncontext,
                                (object obj2) =>
                                {
                                    if (obj2 != null)
                                    {
                                        Issues = (List<ProjectIssue>)obj2;
                                    }
                                });
                            ProjectIssueDetail pid_temp = new ProjectIssueDetail(DateTime.Now, textbox_newComment.Text);
                            IssuesDetailsListBox.Items.Add(pid_temp);
                            if (Selected_ProjectIssue.Details == null)
                                Selected_ProjectIssue.Details = new List<ProjectIssueDetail>();
                            Selected_ProjectIssue.Details.Add(pid_temp);
                            textbox_newComment.Text = "";                            
                        }
                        else
                        {
                            MessageBox.Show("Can't add new comment");
                        }
                    });
            }
        }

        void Button_DoLogout_Click(object sender, RoutedEventArgs e)
        {
            //close logined UI
            TextBlock_LoginCurrent.Visibility = System.Windows.Visibility.Collapsed;
            Button_DoLogout.Visibility = System.Windows.Visibility.Collapsed;
            //update UI            
            Button_DoLogin.Visibility = System.Windows.Visibility.Visible;
            TextBox_Login.Text = ""; TextBox_Login.Visibility = System.Windows.Visibility.Visible;
            TextBox_Password.Text = ""; TextBox_Password.Visibility = System.Windows.Visibility.Visible;

            //clear data and access token
            Token = "";
            Issues.Clear();
            IssuesListBox.Items.Clear();
            textbox_projectIssueTitle.Text = "";
            textbox_projectIssueUsers.Text = "";
            IssuesDetailsListBox.Items.Clear();
        }

        void Button_DoLogin_Click(object sender, RoutedEventArgs e)
        {
            if ((TextBox_Login.Text != "") && (TextBox_Password.Text != ""))
            {
                BLClient.Service_Login(TextBox_Login.Text, TextBox_Password.Text, syncontext,
                    (object obj) =>
                    {
                        if (obj != null)
                        {
                            //update UI
                            TextBlock_LoginCurrent.Text = TextBox_Login.Text;
                            Button_DoLogin.Visibility = System.Windows.Visibility.Collapsed;
                            TextBox_Login.Text = ""; TextBox_Login.Visibility = System.Windows.Visibility.Collapsed;
                            TextBox_Password.Text = ""; TextBox_Password.Visibility = System.Windows.Visibility.Collapsed;
                            //---view logined UI                            
                            TextBlock_LoginCurrent.Visibility = System.Windows.Visibility.Visible;
                            Button_DoLogout.Visibility = System.Windows.Visibility.Visible;

                            Token = (string)obj;                            
                            //load issue list for logined user
                            BLClient.Service_GetIssues(Token, syncontext,
                                (object obj2) =>
                                {
                                    if (obj2 != null)
                                    {
                                        Issues = (List<ProjectIssue>)obj2;
                                    }
                                });
                        }
                        else //wrong login or password
                        {
                            MessageBox.Show("Wrong login or password");
                        }
                    });
            }
        }        
        
        void SetProjectListAndPerformProjects(object obj)
        {
            if (obj != null)
            {                
                //set global variable
                ProjectRoot = (Project)obj;

                //set list of project
                ProjectList.Clear();
                ProjectList.Add(ProjectRoot);

                //perfrorm                
                ProjectsTreeView.Items.Clear();
                TreeViewItem t1 = new TreeViewItem();
                t1.IsExpanded = true;
                t1.Header = ProjectRoot;
                ProjectsTreeView.Items.Add(t1);
                SetProjectTreeRecurse(t1, ProjectRoot);
            }
        }

        void SetProjectTreeRecurse(TreeViewItem tvi, Project pd)
        {
            if (pd.Subprojects != null)
            {
                foreach (Project pdIn in pd.Subprojects)
                {
                    //update project list
                    ProjectList.Add(pdIn);

                    TreeViewItem tNew = new TreeViewItem();
                    tNew.IsExpanded = true;
                    tNew.Header = pdIn;
                    tvi.Items.Add(tNew);
                    SetProjectTreeRecurse(tNew, pdIn);
                }
            }
        }

        void IssuesDetailsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                ProjectIssueDetail pid = (e.AddedItems[0] as ProjectIssueDetail);
                Selected_ProjectIssueDetail = pid; //save selected project issue detail
            }
        }

        void IssuesListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {            
            if (e.AddedItems.Count > 0)
            {
                ProjectIssue pid = (e.AddedItems[0] as ProjectIssue);
                Selected_ProjectIssue = pid; //save selected project issue
                textbox_projectIssueTitle.Text = pid.Name;
                textbox_projectIssueUsers.Text = "";
                if (pid.Persons != null && Users != null)
                {
                    string usersString = "";
                    foreach (User us in Users)
                    {
                        if (pid.Persons.ContainsKey(us.ID))
                            usersString = usersString + us.Name + " ";
                    }
                    textbox_projectIssueUsers.Text = usersString;
                }

                IssuesDetailsListBox.Items.Clear();
                if (pid.Details != null)
                {
                    foreach (ProjectIssueDetail pidet in pid.Details)
                    {
                        IssuesDetailsListBox.Items.Add(pidet);
                    }
                }
            }
        }

        void ProjectsTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if ((e.NewValue != null) && (Issues != null))
            {
                Project pd = ((e.NewValue as TreeViewItem).Header as Project);
                Selected_Project = pd; //save selected project

                PerformIssuesOfSelectedProject();
            }
        }        

        void PerformIssuesOfSelectedProject()
        {
            if (Selected_Project != null)
            {
                List<string> ids = new List<string>();
                if (Selected_Project.IssuesIDs != null) ids.AddRange(Selected_Project.IssuesIDs);
                GetIssuesIDsListOfSubprojects(Selected_Project, ids);

                IssuesListBox.Items.Clear();
                Selected_ProjectIssue = null;
                IssuesDetailsListBox.Items.Clear();
                Selected_ProjectIssueDetail = null;

                foreach (ProjectIssue issue in Issues)
                {
                    if (ids.Contains(issue.ID))
                        IssuesListBox.Items.Add(issue);
                }
            }
        }

        void GetIssuesIDsListOfSubprojects(Project proj, List<string> ids)
        {
            if (proj.Subprojects != null)
            {
                foreach (Project subP in proj.Subprojects)
                {
                    if (subP.IssuesIDs != null) ids.AddRange(subP.IssuesIDs);
                    GetIssuesIDsListOfSubprojects(subP, ids);
                }
            }
        }

        void ClearIssueAndIssueDetailVariableaAndUI()
        {
            Selected_Project = null;
            Selected_ProjectIssue = null;
            Selected_ProjectIssueDetail = null;
            IssuesListBox.Items.Clear();
            IssuesDetailsListBox.Items.Clear();
            textbox_projectIssueTitle.Text = "";
            textbox_projectIssueUsers.Text = "";
        }
    }
}
